#ifndef DATA_STRUCTURES_H
#define DATA_STRUCTURES_H

  #include "basic.h"
  #include "network.h" 
  
  //List struct for dataCache and contentDir
  struct list {
    short size;
    short maxSize;
    
    // in LRU list, head is the oldest item
    struct node * head;
    struct node * tail;
  };
  
  //Node struct
  struct node {
    //payload can be either a dataCache item or
    //a contentDir item or local file name (char *)
  	void * payload;
  	void * next;
  };
  
  //Struct to hold data cache entries
  struct dataCache {
  
    //Filename
    char name[MAX_NAME];
	
    //Actual content
    char content[MAX_CONTENT];
    
    //Length of content
    int contentLength;
  };

  //Struct to hold content directory entries
  struct contentDir {
    //File name
    char name[MAX_NAME];
	
	//Address and port
    unsigned int address;
    unsigned short port;
  };


  //Struct to hold outstanding requests
  struct outstandingReq {
      //Filename requested
	  char name[MAX_NAME];
	  
	  //Store time created
	  time_t timeCreated;
    
    //Flag to denote originator of request.
    // 0 if user-requested.
    // 1 if request is on behalf of another peer
    char originator;
    
    //Counts number of times this request has been
    //requested
    char count;
  };
  
  /********CREATE NODES*************/
  
  //Creates a node that holds a data cache item
  struct node * createCacheItem(char *name, char *content, int length);

  //Creates a node that holds a content directory item
  struct node * createContentDirItem (char * name, struct addressPort senderInfo);
  
  //Creates a node that holds an outstanding request item
  struct node * createOutstandingReqItem (char * name, char originator);
  
  /*******LIST FUNCTIONS********/
  
  //Pushes a given node onto a specified list
  void push(struct list * itemList, struct node *item);
  
  //Searches a given list for a file
  int searchList( struct list * listToSearch, char * name, unsigned char flag);

  //Searches the content directory for duplicates
  int searchContentDir( char * name, struct addressPort ap);

  //Searches the outstanding request list for a name (for user requests only)
  int searchOutstandingReqList( char * name, char * trymsg );
	
	//Retreives from the data cache the requested file.
	struct dataCache * getDataCacheItem(char * filename);

  /*******ITERATOR**************/
  
  //Checks if iterator is at the end of the list
  int hasNext(struct node * it);

  //Creates an iterator over a specified list
  struct node * createIterator (struct list listToIterate);
	
  //Moves the iterator to the next item in the list. 
  struct node * next(struct node ** iteratorAddress);
	
  //Global Data Structures
  extern struct list contentDirectoryList;
  extern struct list dataCacheList;
  extern struct list outstandingRequestsList;
  extern struct list listLocalFiles;
  extern struct list listInitialPeers;


#endif